package org.jdesktop.swingx.renderer;

import java.util.Locale;
import java.util.Map;

import org.jdesktop.swingx.plaf.UIManagerExt;
import org.jdesktop.swingx.util.Contract;

/**
 * A StringValue which looks up localized String representations for objects.
 */
public class LocalizableStringValue implements StringValue {

	private Map<Object, String> lookup;

	private Locale locale;

	private String prefix;

	/**
	 * Instantiates a LocaleStringValue which looks up localized String
	 * representations for items in the map using the JComponent defaultLocale.
	 * 
	 * @param lookup
	 *            a map containing Entries of objects and a string key to look
	 *            up its string representation in the UIManager
	 */
	public LocalizableStringValue(Map<Object, String> lookup) {
		this(lookup, null, null);
	}

	/**
	 * Instantiates a LocaleStringValue which looks up localized String
	 * representations for items in the map using the given Locale.
	 * 
	 * @param lookup
	 *            a map containing Entries of objects and a string key to look
	 *            up its string representation in the UIManager
	 * @param locale
	 *            the locale to lookup the localized strings, may be null to
	 *            denote using JComponent.defaultLocale
	 */
	public LocalizableStringValue(Map<Object, String> lookup, Locale locale) {
		this(lookup, null, locale);
	}

	/**
	 * Instantiates a LocaleStringValue which looks up localized String
	 * representations for items in the map using the JComponent defaultLocale.
	 * 
	 * @param lookup
	 *            a map containing Entries of objects and a string key to look
	 *            up its string representation in the UIManager
	 * @param prefix
	 *            a common prefix for all string keys in the map, may be null to
	 *            denote that the keys should be use as are
	 */
	public LocalizableStringValue(Map<Object, String> lookup, String prefix) {
		this(lookup, prefix, null);
	}

	/**
	 * Instantiates a LocaleStringValue which looks up localized String
	 * representations for items in the map using the given Locale.
	 * 
	 * @param lookup
	 *            a map containing Entries of objects and a string key to look
	 *            up its string representation in the UIManager
	 * @param prefix
	 *            a common prefix for all string keys in the map, may be null to
	 *            denote that the keys should be use as are
	 * @param locale
	 *            the locale to lookup the localized strings, may be null to
	 *            denote using JComponent.defaultLocale
	 */
	public LocalizableStringValue(Map<Object, String> lookup, String prefix, Locale locale) {
		this.lookup = Contract.asNotNull(lookup, "map must not be null");
		this.prefix = prefix;
		setLocale(locale);
	}

	/**
	 * 
	 * @inherited <p>
	 * 
	 *            Implemented to lookup the value's localized string
	 *            representation, if contained in the lookup map. Returns
	 *            toString if not.
	 * 
	 */
	@Override
	public String getString(Object value) {
		String key = lookup.get(value);
		if (key != null) {
			if (prefix != null) {
				key = prefix + key;
			}
			String text = UIManagerExt.getString(key, getLocale());
			if (text != null)
				return text;
		}
		return StringValues.TO_STRING_UI.getString(value);
	}

	// -------------------- implement Localizable

	/**
	 * Sets the Locale to use for lookup of localized string representation.
	 * 
	 * @param locale
	 *            the locale to lookup the localized strings, may be null to
	 *            denote using Locale's default.
	 */
	public final void setLocale(Locale locale) {
		this.locale = locale;
	}

	/**
	 * Returns the Locale to use for lookup, guaranteed to be not null. If the
	 * initial setting had been null, returns current Locale's default.
	 * 
	 * @return the Locale used for lookup.
	 */
	public Locale getLocale() {
		return locale != null ? locale : Locale.getDefault();
	}
}